package com.jxl.dnd.charactercreator.vo.abilityscores
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	[Bindable]
	public class AbilityScore extends EventDispatcher
	{
		
		public static const STRENGTH:String			= "Strength";
		public static const DEXTERITY:String		= "Dexterity";
		public static const CONSTITUTION:String		= "Constitution";
		public static const INTELLIGENCE:String		= "Intelligence";
		public static const WISDOM:String			= "Wisdom";
		public static const CHARISMA:String			= "Charisma";
		
		protected var _abilityModifier:int;
		protected var _value:uint;
		
		public var name:String;
		
		[Bindable(event="abilityModifierChanged")]
		public function get abilityModifier():int
		{
			return getAbilityModifier();
		}
		public function set abilityModifier(value:int):void
		{
			_abilityModifier = value;
			dispatchEvent(new Event("abilityModifierChanged", true));
		}
		
		[Bindable(event="valueChanged")]
		public function get value():uint { return _value; }
		public function set value(newValue:uint):void
		{
			trace("AbilityScore::setter value: " + newValue);
			_value = newValue;
			// NOTE: this'll re-run the getter.  I know it looks weird setting it to 0,
			// but actually, the getter doesn't give a flip what you set it; it
			// instead returns whatever it calculates... just don't set to
			// NaN, or it'll return 0.
			abilityModifier = 0;
			dispatchEvent(new Event("valueChanged", true));
			//DebugWindow.header();
			//DebugWindow.debug("AbilityScore::value setter: " + name + " : " + _value);
		}
		
		public function AbilityScore(name:String, value:uint=10):void
		{
			this.name				= name;
			this.value				= value;
		}
		
		public function getAbilityModifier():int
		{
			// [jwarden 7.6.2008] TODO: Use a logarithm, or some other
			// elegant math algorithm instead of this
			// switch insaity
			//DebugWindow.header();
			//DebugWindow.debug("AbilityScore::getAbilityModifier");
			//DebugWindow.debug("value: " + value);
			
			if(isNaN(value) == true) return 0;
			
			switch(value)
			{
				case 1:
					return -5;
				
				case 2:
				case 3:
					return -4;
				
				case 4:
				case 5:
					return -3;
				
				case 6:
				case 7:
					return -2;
				
				case 8:
				case 9:
					return -1;
				
				case 10:
				case 11:
					return 0;
				
				case 12:
				case 13:
					return 1;
				
				case 14:
				case 15:
					return 2;
				
				case 16:
				case 17:
					return 3;
				
				case 18:
				case 19:
					return 4;
				
				case 20:
				case 21:
					return 5;
					
				case 22:
				case 23:
					return 6;
				
				case 24:
				case 25:
					return 7;
					
				case 26:
				case 27:
					return 8;
				
				case 28:
				case 29:
					return 9;
					
				case 30:
					return 10;
				
				default:
					return 0;
			}
			return 0;
		}
		
		public function buildFromObject(obj:Object):void
		{
			this.name		= obj.name;
			this.value		= obj.value;
		}
		
		public function toObject():Object
		{
			var obj:Object 		= new Object();
			obj.name			= name;
			obj.value			= value;
			return obj;
		}
		
		public function toXML():XML
		{
			var myXML:XML = 
				<abilityscore>
					<name>{name}</name>
					<value>{value}</value>
					<abilitymodifier>{abilityModifier}</abilitymodifier>
				</abilityscore>;
			return myXML;
		}
		
		public function buildFromXML(xml:XML, targetName:String):void
		{
			trace("AbilityScore::buildFromXML: " + xml);
			for each(var abilityScoreNode:XML in xml..abilityscores.abilityscore)
			{
				if(abilityScoreNode.name == targetName)
				{
					name					= abilityScoreNode.name;
					value					= parseInt(abilityScoreNode.value);
					abilityModifier			= parseInt(abilityScoreNode.abilitymodifier);
				}
			}
		}
		
	}
}